/***************************************************************************
 *                                                                         *
 * Copyright (c) 2007 - 2009 Nuvoton Technology Corp. All rights reserved.*
 *                                                                         *
 ***************************************************************************/
 

#ifdef ECOS
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "drv_api.h"
#include "diag.h"
#include "wbio.h"
#include "NUC900_GE.h"
#include "NUC900_reg.h"
#else
#include <stdio.h>
#include "NUC900_GE.h"
#include "wbio.h"
#ifdef _NUC900_
#include "NUC900_reg.h"
#else
#include "reg702.h"
#endif
#endif

typedef	struct
{
  UINT32	PatternA;
  UINT32	PatternB;
} MONOPATTERN;

static MONOPATTERN MonoPatternData[6] =
{{0x00000000, 0xff000000}, // HS_HORIZONTAL
 {0x08080808, 0x08080808}, // HS_VERTICAL
 {0x80402010, 0x08040201}, // HS_FDIAGONAL
 {0x01020408, 0x10204080}, // HS_BDIAGONAL
 {0x08080808, 0xff080808}, // HS_CROSS
 {0x81422418, 0x18244281}  // HS_DIAGCROSS
};

UINT8 ColorPatternData2[2][8*8*4] = // 8*8*4
{
 {
#include "pat8x8-0.dat"
 },
 {
#include "pat8x8-1.dat"
 }
};

int _PatternType; 


///////////////////////////////////////////////////////////////////////////////
//
// Function: init_mono_pattern()
//
// Description:
//   Set the 8x8 mono pattern for following BitBLT functions. 
//
///////////////////////////////////////////////////////////////////////////////
void init_mono_pattern(int opt, int fore_color, int back_color)
{
  UINT32 color32;
  
  /*
  ** If hardware pattern definition is a little different from software.
  ** Need to do the BYTE swap before programming the pattern registers.
  */
    
  outpw(REG_2D_GEPTNA, MonoPatternData[opt].PatternA);
  outpw(REG_2D_GEPTNB, MonoPatternData[opt].PatternB);
  
  color32 = make_color(fore_color);
  outpw(REG_2D_GEFC, color32);
  
  color32 = make_color(back_color);
  outpw(REG_2D_GEBC, color32);  
  
  _PatternType = TYPE_MONO;
}

void init_mono_input_pattern(UINT32 PatternA, UINT32 PatternB, int fore_color, int back_color)
{
  UINT32 color32;
  
  /*
  ** If hardware pattern definition is a little different from software.
  ** Need to do the BYTE swap before programming the pattern registers.
  */
    
  outpw(REG_2D_GEPTNA, PatternA);
  outpw(REG_2D_GEPTNB, PatternB);
  
  color32 = make_color(fore_color);
  outpw(REG_2D_GEFC, color32);
  
  color32 = make_color(back_color);
  outpw(REG_2D_GEBC, color32);  
  
  _PatternType = TYPE_MONO;
}

///////////////////////////////////////////////////////////////////////////////
//
// Function: init_color_pattern()
//
// Description:
//   Set the 8x8 color pattern for following BitBLT functions.. 
//   This function transfers those forms
//   RGB888 to RGB565 or RGB332
//   RGB565 to RGB332 or RGB888
//   RGB332 to RGB565 or RGB888
///////////////////////////////////////////////////////////////////////////////
void init_color_pattern(int patformat, void *patdata) 
{
  UINT8 *ptr_pat;
  UINT8 *ptr8, r8, g8, b8;
  UINT16 *ptr16, r16, g16, b16, g16_1, g16_2;
  UINT32 *ptr32, r32, g32, b32, g32_1, g32_2;
  int idx;
  
  //ptr_pat = (UINT8 *)ColorPatternData2[opt];  //smf
  ptr_pat = (UINT8 *)patdata;
  if(patformat == RGB888)
  {
	  if (GFX_BPP==8)
	  {
	    ptr8 = (UINT8 *)GFX_PAT_ADDR;
	    for (idx=0; idx<64; idx++)
	    {
	      b8 = (UINT8)(*ptr_pat++) & 0xc0; // 2 bits
	      g8 = (UINT8)(*ptr_pat++) & 0xe0; // 3 bits
	      r8 = (UINT8)(*ptr_pat++) & 0xe0; // 3 bits
	      ptr_pat++;
	      *ptr8++ = r8 | (g8>>3) | (b8>>6);
	    }
	  }
	  else if (GFX_BPP==16)
	  {
	    ptr16 = (UINT16 *)GFX_PAT_ADDR;
	    for (idx=0; idx<64; idx++)
	    {
	      b16 = (UINT16)(*ptr_pat++) & 0x000f8; // 5 bits
	      g16 = (UINT16)(*ptr_pat++) & 0x000fc; // 6 bits
	      r16 = (UINT16)(*ptr_pat++) & 0x000f8; // 5 bits
	      ptr_pat++; 
	      *ptr16++ = (r16<<8) | (g16<<3) | (b16>>3);
	    }
	  }
	  else if (GFX_BPP==32)
	  {
	    ptr32 = (UINT32 *)GFX_PAT_ADDR;
	    for (idx=0; idx<64; idx++)
	    {
	      b32 = (UINT32)(*ptr_pat++);
	      g32 = (UINT32)(*ptr_pat++);
	      r32 = (UINT32)(*ptr_pat++);
	      ptr_pat++;
	      *ptr32++ = (r32<<16) | (g32<<8) | b32;
	    }
	  }
  }
  else if(patformat == RGB565)
  {
  		if (GFX_BPP==8)
		{
		  ptr8 = (UINT8 *)GFX_PAT_ADDR;
		  
		  for (idx=0; idx<64; idx++)
		  {
		    b8 = (UINT8)(*ptr_pat++) & 0x00018; // 2 bits
      		g8 = (UINT8)(*ptr_pat) & 0x00007;  // 3 bits
		    r8 = (UINT8)(*ptr_pat++) & 0x000e0;  // 3bits
		    *ptr8++ = r8 | (g8<<2) | (b8>>3);
		  }
		} 
		else if (GFX_BPP==16)
		{
		  ptr16 = (UINT16 *)GFX_PAT_ADDR;
		    
		  for (idx=0; idx<64; idx++)
		  {
		    *ptr16++ = (*ptr_pat) | (*(ptr_pat+1)) << 8;
		    ptr_pat+=2;
		  }
		}
		else if (GFX_BPP==32)
		{
		  ptr32 = (UINT32 *)GFX_PAT_ADDR;
		    
		  for (idx=0; idx<64; idx++)
		  {
		    b32 = (UINT8)(*ptr_pat) & 0x1f;      // 5 bits 
		    g32_1 = (UINT8)(*ptr_pat++) & 0xe0;  // front 3 bits
		    g32_2 = (UINT8)(*ptr_pat) & 0x07;    // back 3 bits
		    g32 = ((g32_1>>5) | (g32_2<<3))<<2;
		    r32 = (UINT8)(*ptr_pat++) & 0xf8;    // 5 bits
		    *ptr32++ = 0<<24 | (r32<<16) | (g32<<8) | (b32<<3);
		  }
		}
  }
  else if(patformat == RGB332)
  {
  		if (GFX_BPP==8)
		{
		  ptr8 = (UINT8 *)GFX_PAT_ADDR;
		  
		  for (idx=0; idx<64; idx++)
		  {
		    *ptr8++ = *ptr_pat;
		    ptr_pat++;
		  }
		} 
		else if (GFX_BPP==16)
		{
		  ptr16 = (UINT16 *)GFX_PAT_ADDR;
		    
		  for (idx=0; idx<64; idx++)
		  {
		    r16 = (UINT8)(*ptr_pat) & 0xe0; // 3 bits
		    g16_1 = (UINT8)(*ptr_pat) & 0x10;
		    g16_2 = (UINT8)(*ptr_pat) & 0x0c;
		    g16 = (g16_1>>2) | (g16_2>>2);
		    b16 = (UINT8)(*ptr_pat++) & 0x3; // 2 bits
		    *ptr16++ = (r16<<8) | (g16<<8) | (b16<<3);
		  }
		}
		else if (GFX_BPP==32)
		{
		  ptr32 = (UINT32 *)GFX_PAT_ADDR;
		    
		  for (idx=0; idx<64; idx++)
		  {
		    r32 = (UINT8)(*ptr_pat) & 0xe0;  // 3 bits 
		    g32 = (UINT8)(*ptr_pat) & 0x1c;  // 3 bits
		    b32 = (UINT8)(*ptr_pat++) & 0x3;  // 2 bits
		    *ptr32++ = 0<<24 | (r32<<15) | (g32<<11) | (b32<<6);
		  }
		}
  }
  
  _PatternType = TYPE_COLOR;  
}


